package com.netflix.eureka.util;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MeasuredRate {

    private static final Logger logger = LoggerFactory.getLogger(MeasuredRate.class);

    private final AtomicLong lastBucket = new AtomicLong(0);
    private final AtomicLong currentBucket = new AtomicLong(0);

    private final long sampleInterval;
    private final Timer timer;

    private volatile boolean isActive;

    public MeasuredRate(long sampleInterval) {
        this.sampleInterval = sampleInterval;
        this.timer = new Timer("Eureka-MeasureRateTimer", true);
        this.isActive = false;
    }

    public synchronized void start() {
        if (!isActive) {
            //激活记录最后一分钟的续约数量任务 sampleInterval 可以从代码看到是 1分钟
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    try {
                        // Zero out the current bucket.
                        // 每分钟都会从头开始计算
                        lastBucket.set(currentBucket.getAndSet(0));
                    } catch (Throwable e) {
                        logger.error("Cannot reset the Measured Rate", e);
                    }
                }
            }, sampleInterval, sampleInterval);
            isActive = true;
        }
    }

    public synchronized void stop() {
        if (isActive) {
            timer.cancel();
            isActive = false;
        }
    }

    public long getCount() {
        return lastBucket.get();
    }

    /**
     * 每次续约都会自增1
     * 通过查找调用关系，可以看到increment()方法被调用的地方AbstractInstanceRegistry里的renew方法，正是续约的方法
     * 知晓了续约数量的记录后再往下看过期节点清理任务,EvictionTask
     */
    public void increment() {
        currentBucket.incrementAndGet();
    }
}
